/**
 * TManPassiveThread.java
 * ************************** 
 * @date May 5, 2011
 * @author Michele Tamburini
 * 
 * **************************
 */
package gossipServices.bootstraping.tman;

import gossipServices.basic.nodeDescriptors.NodeDescriptor;
import gossipServices.basic.view.ConcretePartialView;
import gossipServices.basic.view.PartialView;
import gossipServices.gossipMessages.TManMessage;
import gossipServices.gossipThread.PassiveGossipThreadInterface;
import gossipServices.pss.PeerSamplingServiceAPI;
import messages.Message;

/**
 * Description: 
 * The passive thread of TMan. 
 * It extends the {@link TManMiddleware} class in order to share with 
 * the active thread the shared variables. 
 * It Implements the {@link PassiveGossipThreadInterface}.
 *
 */
public class TManPassiveThread extends TManMiddleware implements
		PassiveGossipThreadInterface {

	/**
	 * @param string
	 * @param cycleLengthMsec
	 * @param tManView
	 * @param pss
	 * @param tmanNm
	 * @param localNodeDescriptor
	 * @param rankingMet
	 * @param messageSize
	 * @param phi
	 */
	public TManPassiveThread(String name, long cycleLengthMsec,
			PartialView initView, PeerSamplingServiceAPI pss,
			TManNetworkManager tmanNm, NodeDescriptor localNodeDescriptor,
			TManRankingMethod rankingMet, int messageSize, int phi, int tabuListSize, String subcloudID) {
		super(name, cycleLengthMsec, initView, pss, tmanNm,localNodeDescriptor, rankingMet, 
				messageSize, phi, tabuListSize, subcloudID);
		gossipProtocol = this;
	}

	@Override
	public void passiveThreadInstructions() throws InterruptedException {
		Message msgQ = netServ.receive();
//		System.out.println("PASSIVE: received-> "+msgQ);
		NodeDescriptor q = msgQ.getSender();
		PartialView buffer = new ConcretePartialView(0);
		synchronized (view) {
			buffer.merge(view);
			buffer.insertNodeDescriptor(myDescriptor);
			// ----------------------------------
//			buffer = ranker.rank(q, buffer); <- (**) modification respect the code in the paper
			// ----------------------------------
		}
		Message myMsg = new TManMessage(myDescriptor, q, 
				buffer.head(m), TManPassiveThread.class, subcloudID);
//		System.out.println("PASSIVE: sending-> "+myMsg);
		netServ.send(myMsg, q);
		PartialView bufferQ = (PartialView) msgQ.getBody();
		synchronized (view) {
			view.merge(bufferQ);
			// ----------------------------------
			view = ranker.rank(myDescriptor, view); //  <-(**) additional line not inserted in the paper
			// ----------------------------------
			cycles++;
			debugPrint();
		}
		terminationCheck();
		/*
		 * NOTE: (**)
		 * In the paper "T-Man: Gossip-based fast overlay topology construction"
		 * of 2009 the algorithm finishes with the merging of view
		 * by bufferP at line 78.
		 * I added the (**) instruction, at line 80, following the previous paper:
		 * "T-Man: Gossip-based overlay topology management", (2006),
		 * where they used the function: "view <- selectView(bufferP)".
		 * In this way a node locally is able to update its view according
		 * to the specified ranking method, instead of only receiving
		 * the bufferP in the message and merge as it is into the view.
		 * I think that this modification can improve the robustness of the algorithm
		 * to the joining of new nodes and the removal of some nodes in the overlay.
		 *	  
		 */
	}

	@Override
	public void gossipThreadInstructions() throws InterruptedException {
		passiveThreadInstructions();
	}

}
